package com.me.batm.views;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.math.Vector2;
import com.me.batm.GameConstants;
import com.me.batm.models.GameWorld;
import com.me.batm.models.Player;

public class GameSoundService {
	private static final String TAG = GameSoundService.class.getSimpleName();
	private GameWorld gameWorld;
	
	private Sound heartBeatSound;
	private boolean isPlayingHeartBeat;
	private long idHeartBeat;
	
	private Sound[] gameMusic;
	private Sound teleportSound;
	private boolean isPlayingMusic;
	private int iteratorMusic;
	private long idMusic;
	
	private final float SLOW_SPEED = 0.7f;
	private final float NORMAL_SPEED = 1.0f;
	private final float MINIMUM_VOLUME = 0.05f;
	private final float MAXIMUM_VOLUME = 0.8f;
	
	private float actualVolume;
	private float actualSpeed;
	
	public GameSoundService() {
		loadResources();
		isPlayingHeartBeat = false;
		isPlayingMusic = false;
		actualSpeed = NORMAL_SPEED;
	}
	
	private void loadResources(){
		heartBeatSound = Gdx.audio.newSound(Gdx.files.internal("latidomono.wav"));
		
		gameMusic = new Sound[2];
//		gameMusic[0] = Gdx.audio.newSound(Gdx.files.internal("world_song_0.mp3"));
		gameMusic[0] = Gdx.audio.newSound(Gdx.files.internal("world_song_2.wav"));
		
		teleportSound = Gdx.audio.newSound(Gdx.files.internal("teleport.wav"));
	}
	
	public void setGameWorld(GameWorld gareveWorld){
		this.gameWorld = gareveWorld;
	}
	
	public void playHeartBeat() {
		if(!isPlayingHeartBeat) {
			idHeartBeat = heartBeatSound.play(1f);
			heartBeatSound.setLooping(idHeartBeat, true);
			isPlayingHeartBeat = true;
		}
	}
	
	public void stopHeartBeat(){
		heartBeatSound.stop();
		isPlayingHeartBeat = false;
	}
	
	public void playGameMusic(int theme) {
		if(!isPlayingMusic) {
			idMusic = gameMusic[theme].play(MAXIMUM_VOLUME);
			gameMusic[theme].setLooping(idMusic, true);
			iteratorMusic = theme;
			isPlayingMusic = true;
		}
	}
	
	public void stopGameMusic() {
		if(isPlayingMusic) {
			gameMusic[iteratorMusic].stop();
			heartBeatSound.setLooping(idHeartBeat, true);
			isPlayingMusic = false;
		}
	}
	
	public void updateDirectionSound(Vector2 player, Vector2 target, Vector2 playerDirection) {
		Vector2 dir = target.tmp().sub(player);
		float angle = dir.angle() - (playerDirection.angle() - 90f);
		float angleRadians = (float) (angle * Math.PI / 180f);
		float panVal = (float) Math.cos(angleRadians);
//		Gdx.app.log(TAG, ((int) (panVal*100f)) + " , " + player + " , " + target);
		heartBeatSound.setPan(idHeartBeat, panVal, 1f);
	}
	
	public void update(float delta) {
		if(gameWorld.player.speedFactor >= Player.SPEED) {
			if(gameWorld.normalSpeed) {
				if(actualSpeed != NORMAL_SPEED) {
					actualSpeed = Math.min(NORMAL_SPEED, actualSpeed + delta/2f);
				}
				if(actualVolume != MAXIMUM_VOLUME) {
					actualVolume = Math.min(MAXIMUM_VOLUME, actualVolume + delta/2f);
				}
			}
			else {
				if(actualSpeed != SLOW_SPEED) {
					actualSpeed = Math.max(SLOW_SPEED, actualSpeed - delta/2f);
				}
				if(actualVolume != MINIMUM_VOLUME) {
					actualVolume = Math.max(MINIMUM_VOLUME, actualVolume - delta/2f);
				}
			}
		}
		else {
			if(actualSpeed != SLOW_SPEED) {
				actualSpeed = Math.max(SLOW_SPEED, actualSpeed - delta/2f);
			}
		}
		
//		if(isPlayingHeartBeat) heartBeatSound.setPitch(idHeartBeat, actualSpeed);
		if(isPlayingMusic) {
			gameMusic[iteratorMusic].setPitch(idMusic, actualSpeed);
			gameMusic[iteratorMusic].setVolume(idMusic, actualVolume);
		}

		if(gameWorld.normalSpeed) { // Game Music
			stopHeartBeat();
			playGameMusic(0);
		}
		else { // Heart Beat
//			stopGameMusic();
			playHeartBeat();
			updateDirectionSound(gameWorld.player.getCenterPosition(), gameWorld.target.getCenterPosition(), gameWorld.player.direction);
		}
		
		if(gameWorld.playTeleportSound){
			teleportSound.play();
			gameWorld.playTeleportSound = false;
		}
	}

	public void dispose() {
		heartBeatSound.dispose();
		for(int i = 0; i < gameMusic.length;i++)
			if(gameMusic[i] != null)
				gameMusic[i].dispose();
	}
}
